package com.dongnao.demo.database.utils;

import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;

import com.dongnao.demo.database.annotation.DbFiled;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DbUtils {

    private static final String TAG = "com.dongnao.database";



    public static void checkNull(Object... objects) {
        if(objects == null){
            throw new NullPointerException();
        }
        for(Object obj:objects){
            if(obj == null) throw new NullPointerException();
        }
    }

    /**
     * 生成建表语句
     * @param tableName 表名
     * @param entityClass 建表的javaBean
     * @return
     */
    public static String genTabCreatorSql(String tableName, Class<?> entityClass){
        StringBuffer sql = new StringBuffer("CREATE TABLE IF NOT EXISTS ");
        sql.append(tableName);
        sql.append("(");
        Field[] fields = entityClass.getDeclaredFields();
        for(Field field:fields){
            Class type = field.getType();
            DbFiled fieldAnnotation = field.getAnnotation(DbFiled.class);
            String filedName = field.getName();
            if(fieldAnnotation !=null){
                filedName = fieldAnnotation.value();
            }

            if(type == String.class){
                sql.append(filedName).append(" TEXT,");
            }else if(type == int.class){
                sql.append(filedName).append(" INTEGER,");
            }else if(type == long.class){
                sql.append(filedName).append(" BIGINT,");
            }else if(type == double.class){
                sql.append(filedName).append(" DOUBLE,");
            }else if(type == byte[].class){
                sql.append(filedName).append(" BLOB,");
            }else{
                Log.i(TAG, "Filed Type Not Support.");
                continue;
            }
        }
        if(sql.charAt(sql.length()-1) == ','){
            sql.deleteCharAt(sql.length()-1);
        }
        sql.append(")");
        return sql.toString();
    }

    public static ContentValues genContentValues(Map<String, Field> cacheMap, Object entity) {
        ContentValues cv = new ContentValues();
        Set<String> columnNames = cacheMap.keySet();
        for(String columnName : columnNames){
            Field columnField = cacheMap.get(columnName);
            if(columnField == null) continue;
            columnField.setAccessible(true);
            try {
                Object obj = columnField.get(entity);
                if(obj == null) continue;
                Class<?> type = columnField.getType();
                if(type == String.class){
                    cv.put(columnName, (String)obj);
                }else if(type == int.class){
                    cv.put(columnName, (int) obj);
                }else if(type == long.class){
                    cv.put(columnName, (long) obj);
                }else if(type == double.class){
                    cv.put(columnName, (double) obj);
                }else if(type == byte[].class){
                    cv.put(columnName, (byte[]) obj);
                }else{
                    Log.i(TAG, "Filed Type Not Support.");
                    continue;
                }
            } catch (IllegalAccessException e) {
                Log.e(TAG, "genContentValues: ", e);
                continue;
            }
        }
        return cv;
    }

    public static <T> List<T> invokeObject(Class<T> entityClass, Map<String, Field> cacheMap, Cursor cursor) {
        List<T> all = new ArrayList<>();
        while(cursor.moveToNext()){
            T entity = null;
            try {
                entity = entityClass.newInstance();
            } catch (Exception e) {
                Log.e(TAG, "queryAll: ", e);
                continue;
            }
            for(String columnName:cacheMap.keySet()){
                if(TextUtils.isEmpty(columnName)) continue;
                Field columnField = cacheMap.get(columnName);
                if(columnField == null) continue;
                columnField.setAccessible(true);
                int columnIndex = cursor.getColumnIndex(columnName);
                if(columnIndex < 0) continue;

                try {
                    Class type = columnField.getType();
                    if(type == String.class){
                        columnField.set(entity, cursor.getString(columnIndex));
                    }else if(type == int.class){
                        columnField.setInt(entity, cursor.getInt(columnIndex));
                    }else if(type == long.class){
                        columnField.setLong(entity, cursor.getLong(columnIndex));
                    }else if(type == double.class){
                        columnField.setDouble(entity, cursor.getDouble(columnIndex));
                    }else if(type == byte[].class){
                        columnField.set(entity, cursor.getBlob(columnIndex));
                    }else{
                        Log.i(TAG, "Filed Type Not Support.");
                        continue;
                    }
                } catch (IllegalAccessException e) {
                    Log.e(TAG, "queryAll: ", e);
                    continue;
                }
            }
            all.add(entity);
        }
        return all;
    }
}
